package com.zrrd.gmall.product.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zrrd.gmall.model.product.*;
import com.zrrd.gmall.product.mapper.*;
import com.zrrd.gmall.product.service.SkuInfoService;
import com.zrrd.gmall.service.cache.GmallCache;
import com.zrrd.gmall.service.constant.RedisConst;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoMapper, SkuInfo> implements SkuInfoService {

    @Autowired
    private SpuImageMapper spuImageMapper;
    @Autowired
    private SpuSaleAttrMapper spuSaleAttrMapper;
    @Autowired
    private SkuImageMapper skuImageMapper;
    @Autowired
    private SkuSaleAttrValueMapper skuSaleAttrValueMapper;
    @Autowired
    private SkuAttrValueMapper skuAttrValueMapper;
    @Autowired
    private BaseCatefgoryViewMapper baseCatefgoryViewMapper;
    @Autowired
    private BaseAttrInfoMapper baseAttrInfoMapper;

    //获取Sku基本信息(加入缓存逻辑)
    @Override
    //使用自定义注解来替换缓存逻辑 prefix：存入到redis中的key的前缀 比如这里是sku:
    @GmallCache(prefix = "skuInfo:")
    public SkuInfo getSkuInfo(Long skuId) throws InterruptedException {
        //无论以上逻辑返回什么 最终要给一个兜底的数据返回 从Mysql中返回的
        return this.getSkuInfoDB(skuId);
    }

    //从数据库中查询sku基本信息
    public SkuInfo getSkuInfoDB(Long skuId) {
        //1.获取Sku基本信息
        SkuInfo skuInfo = this.getById(skuId);
        //2.根据SkuId查询Sku图片
        QueryWrapper<SkuImage> wrapper = new QueryWrapper<>();
        wrapper.eq("sku_id", skuId);
        List<SkuImage> skuImages = skuImageMapper.selectList(wrapper);
        //3.给Sku基本信息对象 设置sku图片集合
        skuInfo.setSkuImageList(skuImages);
        //4.返回Sku对象
        return skuInfo;
    }


    @Override
    public List<SpuImage> getSpuImageList(Long spuId) {
        QueryWrapper<SpuImage> wrapper = new QueryWrapper<>();
        wrapper.eq("spu_id", spuId);
        return spuImageMapper.selectList(wrapper);
    }

    @Override

    public List<SpuSaleAttr> getSpuSaleAttrList(Long spuId) {
        return spuSaleAttrMapper.getSpuSaleAttrList(spuId);
    }

    @Override
    @Transactional
    public void saveSkuInfo(SkuInfo skuInfo) {
        //1.保存Sku基本信息 sku_info
        this.save(skuInfo);
        //2.保存Sku图片信息 sku_image
        List<SkuImage> skuImageList = skuInfo.getSkuImageList();
        for (SkuImage skuImage : skuImageList) {
            skuImage.setSkuId(skuInfo.getId());
            skuImageMapper.insert(skuImage);
        }
        //3.保存Sku选择的销售属性信息 sku_sale_attr_value(和Spu销售属性的关系表)
        List<SkuSaleAttrValue> saleAttrValueList = skuInfo.getSkuSaleAttrValueList();
        for (SkuSaleAttrValue skuSaleAttrValue : saleAttrValueList) {
            skuSaleAttrValue.setSpuId(skuInfo.getSpuId());
            skuSaleAttrValue.setSkuId(skuInfo.getId());
            skuSaleAttrValueMapper.insert(skuSaleAttrValue);
        }
        //4.保存Sku选择的平台属性信息 sku_attr_value(和平台属性的关系表)
        List<SkuAttrValue> attrValueList = skuInfo.getSkuAttrValueList();
        for (SkuAttrValue skuAttrValue : attrValueList) {
            skuAttrValue.setSkuId(skuInfo.getId());
            skuAttrValueMapper.insert(skuAttrValue);
        }
    }

    //sku的分类信息
    @Override
    @GmallCache(prefix = "baseCategory:")
    public BaseCategoryView getBaseCategoryViewById(Long category3Id) {
        return baseCatefgoryViewMapper.selectById(category3Id);
    }

    @Override
    @GmallCache(prefix = "skuPrice:")
    public BigDecimal getSkuPrice(Long skuId) {
        SkuInfo skuInfo = this.getById(skuId);
        if (skuInfo != null) {
            return skuInfo.getPrice();
        }
        return new BigDecimal("0");
    }

    //销售属性
    @Override
    @GmallCache(prefix = "spuSaleAttr:")
    public List<SpuSaleAttr> getSpuSaleAttrListBySkuId(Long skuId, Long spuId) {
        return spuSaleAttrMapper.getSpuSaleAttrListBySkuId(skuId, spuId);
    }


    @Override
    public Map getSaleAttrValueBySku(Long spuId) {
        //创建最终返回的Map集合
        Map map = new HashMap();
        //获取mapper层的结果
        List<Map> mapList = skuSaleAttrValueMapper.getSaleAttrValueBySku(spuId);
        //遍历结果
        for (Map m : mapList) {
            map.put(m.get("value_ids"), m.get("sku_id"));
        }
        return map;
    }

    @Override
    //首页的访问频率也很高 所以这里的分类信息也加入到缓存
    @GmallCache(prefix = "category:")
    public List<JSONObject> getBaseCategoryList() {
        //创建最终返回的集合
        List<JSONObject> list = new ArrayList<>();

        //查询分类的视图 获取3个分类表的所有数据
        List<BaseCategoryView> categoryViews = baseCatefgoryViewMapper.selectList(null);

        //对视图集合的数据 按照1级分类ID 进行分组 将1级分类id抽离出来 返回一个map集合 key：1级分类id value:当前的数据
        Map<Long, List<BaseCategoryView>> categoryMap = categoryViews.stream().
                collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));

        //定义代表当前是第几条数据的变量
        int index = 1;

        //遍历Map集合->获取一级分类下所有数据
        for (Map.Entry<Long, List<BaseCategoryView>> entry1 : categoryMap.entrySet()) {
            //获取一级分类ID
            Long category1Id = entry1.getKey();
            //获取一级分类下所有数据的集合
            List<BaseCategoryView> category2List = entry1.getValue();

            //创建1级分类的Json对象
            JSONObject category1 = new JSONObject();
            category1.put("index", index);
            category1.put("categoryId", category1Id);
            category1.put("categoryName", category2List.get(0).getCategory1Name());

            //变量自增
            index++;

            //获取二级分类集合的Map
            Map<Long, List<BaseCategoryView>> cageory2Map = category2List.stream().
                    collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
            //声明二级分类的json集合
            List<JSONObject> category2Child = new ArrayList<>();
            //遍历二级分类的Map
            for (Map.Entry<Long, List<BaseCategoryView>> entry2 : cageory2Map.entrySet()) {
                //获取二级分类的ID
                Long category2Id = entry2.getKey();
                //获取二级分类下的所有集合数据
                List<BaseCategoryView> category3List = entry2.getValue();
                //创建二级分类Json对象
                JSONObject category2 = new JSONObject();
                category2.put("categoryId",category2Id);
                category2.put("categoryName",category3List.get(0).getCategory2Name());
                //将二级分类json对象 添加进二级json集合
                category2Child.add( category2);

                //声明三级分类的json集合
                List<JSONObject> category3Child = new ArrayList<>();
                //直接遍历三级分类的集合
                for (BaseCategoryView baseCategoryView : category3List) {
                    //创建三级分类的json对象
                    JSONObject category3 = new JSONObject();
                    category3.put("categoryId",baseCategoryView.getCategory3Id());
                    category3.put("categoryName",baseCategoryView.getCategory3Name());
                    //将三级分类的json对象 添加进三级分类的json集合
                    category3Child.add(category3);
                }
                //将三级分类的集合 设置给二级分类的对象
                category2.put("categoryChild",category3Child);

            }
            //将二级分类的集合 设置给一级分类对象
            category1.put("categoryChild",category2Child);
            //将一级分类对象 添加进最终要返回的json集合
            list.add(category1);
        }

        return list;
    }

    @Override
    public List<BaseAttrInfo> getBaseAttrInfo(Long skuId) {
        return baseAttrInfoMapper.getAttrListBySkuId(skuId);
    }


}
